#include "endoscope_window.h"
#include <QStyle>
#include <QMediaDevices>
#include <QPermission>
#include <QApplication>
#include <QDir> 

#include <QMenu>

// 录像头文件新增
#include <QTimer>
#include <QDateTime>
#include <QMediaFormat> 
#include <QMediaRecorder> 


#include <QVideoSink>

// 添加 OpenCV 头文件
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>

#include <iostream>
using namespace std;

EndoscopeWindow::EndoscopeWindow(QWidget *parent)
    : QMainWindow(parent)
    , isSmoothing(false)
    , isWhitening(false)
{
    setupUI();
}

EndoscopeWindow::~EndoscopeWindow()
{
}

// 新增初始化摄像头方法
void EndoscopeWindow::initializeCamera()
{

    cout << "Initializing camera..." << endl;
    const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
    cout << "Found " << cameras.size() << " cameras" << endl;
    // const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
    if (!cameras.isEmpty()) {
        camera = new QCamera(cameras.first(), this);
        // 添加错误处理
        connect(camera, &QCamera::errorOccurred, this, &EndoscopeWindow::handleCameraError);

        captureSession = new QMediaCaptureSession(this);
        captureSession->setCamera(camera);

        // 添加视频帧处理
        QVideoSink *videoSink = new QVideoSink(this);
        
        connect(videoSink, &QVideoSink::videoFrameChanged, this, 
            [this](const QVideoFrame &frame) {
                if (frame.isValid()) {
                    QVideoFrame modifiedFrame = frame;
                    if (isSmoothing || isWhitening) {  // 只在开启效果时处理
                        processFrame(modifiedFrame);
                    }
                    viewfinder->videoSink()->setVideoFrame(modifiedFrame);
                }
            });
    
        captureSession->setVideoOutput(viewfinder);
        captureSession->setVideoSink(videoSink);

        // 初始化图像捕获
        imageCapture = new QImageCapture(this);
        captureSession->setImageCapture(imageCapture);

        
        
        // 连接图像保存信号
        connect(imageCapture, &QImageCapture::imageSaved, this, &EndoscopeWindow::imageSaved);

        // 检查摄像头状态
        if (camera->isAvailable()) {
            camera->start();
            cout << "Camera started successfully" << endl;
        } else {
            cout << "Camera is not available" << endl;
        }
    } else {
        cout << "No cameras found" << endl;
    }

    // 录像逻辑
    // 初始化录像功能
    mediaRecorder = new QMediaRecorder(this);
    captureSession->setRecorder(mediaRecorder);

    // 设置音频输入设备
    const QList<QAudioDevice> audioInputs = QMediaDevices::audioInputs();
    if (!audioInputs.isEmpty()) {
        captureSession->setAudioInput(new QAudioInput(audioInputs.first(), this));
    }
    
    // 设置录像输出位置和格式
    QString saveDir = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation) + "/YIGasMed";
    QDir().mkpath(saveDir);
    
    QMediaFormat format(QMediaFormat::MPEG4);
    format.setVideoCodec(QMediaFormat::VideoCodec::H264);

    // 添加音频编解码器
    format.setAudioCodec(QMediaFormat::AudioCodec::AAC); // 添加

    mediaRecorder->setMediaFormat(format);
    mediaRecorder->setQuality(QMediaRecorder::HighQuality);

    mediaRecorder->setAudioSampleRate(44100);  // 设置音频采样率
    mediaRecorder->setAudioBitRate(128000);    // 设置音频比特率
    
    // 连接录像相关信号
    connect(mediaRecorder, &QMediaRecorder::errorOccurred, this, &EndoscopeWindow::handleRecordingError);
    connect(mediaRecorder, &QMediaRecorder::recorderStateChanged, this, &EndoscopeWindow::handleRecordingFinished);
    
    // 初始化录像指示器定时器
    recordingTimer = new QTimer(this);
    recordingTimer->setInterval(500); // 500ms闪烁间隔
    connect(recordingTimer, &QTimer::timeout, this, &EndoscopeWindow::updateRecordingIndicator);
    
    isRecording = false;
    
    pulseScale = 1.0;
    pulseGrowing = true;

}

void EndoscopeWindow::setupUI()
{
    // 设置窗口标题和大小
    setWindowTitle("YIGasMed");
    resize(800, 600);

    // 创建中央部件
    centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);

    // 创建主布局
    QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget);

    // 左侧状态面板
    QWidget *leftPanel = new QWidget;
    QVBoxLayout *leftLayout = new QVBoxLayout(leftPanel);
    QLabel *statusLabel = new QLabel("设备状态");
    leftLayout->addWidget(statusLabel);
    leftLayout->addStretch();

    // 中间视频显示区域
    // videoWidget = new QWidget;
    // videoWidget->setStyleSheet("background-color: #333333;");
    videoWidget = new QWidget;
    QVBoxLayout *videoLayout = new QVBoxLayout(videoWidget);
    
    // 创建视频显示组件
    viewfinder = new QVideoWidget(this);
    videoLayout->addWidget(viewfinder);


    // 请求摄像头权限
    QCameraPermission cameraPermission;
    QMicrophonePermission microphonePermission;

    switch (qApp->checkPermission(cameraPermission)) {
    case Qt::PermissionStatus::Granted:
        // 已经有权限，可以直接使用摄像头
        cout << "Camera permission granted" << endl;
        initializeCamera();
        break;
    case Qt::PermissionStatus::Denied:
        // 权限被拒绝
        cout << "Camera permission denied" << endl;
        break;
    case Qt::PermissionStatus::Undetermined:
        // 请求权限
        qApp->requestPermission(cameraPermission, [this](const QPermission &permission) {

            if (permission.status() == Qt::PermissionStatus::Granted) {
                // 权限获取成功
                cout << "Camera permission granted" << endl;
                initializeCamera();
            } else {
                // 权限获取失败
                cout << "Undetermined Camera permission denied" << endl;
            }
        });
        break;
    }

    // 请求麦克风权限
    switch (qApp->checkPermission(microphonePermission)) {
        case Qt::PermissionStatus::Granted:
            cout << "Microphone permission granted" << endl;
            break;
        case Qt::PermissionStatus::Denied:
            cout << "Microphone permission denied" << endl;
            break;
        case Qt::PermissionStatus::Undetermined:
            qApp->requestPermission(microphonePermission, [](const QPermission &permission) {
                if (permission.status() == Qt::PermissionStatus::Granted) {
                    cout << "Microphone permission granted" << endl;
                } else {
                    cout << "Microphone permission denied" << endl;
                }
            });
            break;
    }

    videoWidget->setStyleSheet("background-color: #333333;");

    // 右侧控制面板
    QWidget *rightPanel = new QWidget;
    QVBoxLayout *rightLayout = new QVBoxLayout(rightPanel);

    // 创建时间和电量标签
    timeLabel = new QLabel;
    timeLabel->setStyleSheet("color: white; font-size: 14px; padding: 5px;");
    batteryLabel = new QLabel("100%");
    batteryLabel->setStyleSheet("color: white; font-size: 14px; padding: 5px;");

    // 添加时间和电量标签到右侧面板顶部
    rightLayout->addWidget(timeLabel);
    rightLayout->addWidget(batteryLabel);

    // 设置定时器更新时间
    timeUpdateTimer = new QTimer(this);
    connect(timeUpdateTimer, &QTimer::timeout, this, &EndoscopeWindow::updateDateTime);
    timeUpdateTimer->start(1000);
    updateDateTime();
    // 创建时间和电量标签 结束

    // 创建右侧按钮
    createButtons(rightLayout);

    // 亮度调节滑块
    brightnessSlider = new QSlider(Qt::Vertical);
    brightnessSlider->setRange(0, 100);
    brightnessSlider->setValue(50);

    // 添加按钮到右侧面板
    rightLayout->addWidget(autoButton);
    rightLayout->addWidget(cameraButton);
    rightLayout->addWidget(videoButton);
    rightLayout->addWidget(brightnessSlider);
    rightLayout->addWidget(freezeButton);
    rightLayout->addWidget(saveButton);
    rightLayout->addWidget(settingsButton);
    rightLayout->addStretch();

    // 设置右侧面板的固定宽度
    rightPanel->setFixedWidth(100);
    leftPanel->setFixedWidth(100);

    // 将所有部件添加到主布局
    mainLayout->addWidget(leftPanel);
    mainLayout->addWidget(videoWidget);
    mainLayout->addWidget(rightPanel);
}

void EndoscopeWindow::createButtons(QVBoxLayout *rightLayout)
{
    // 创建按钮并设置图标
    autoButton = new QPushButton("AUTO");
    cameraButton = new QPushButton("拍照");
    videoButton = new QPushButton("录像");
    freezeButton = new QPushButton("冻结");
    saveButton = new QPushButton("保存");
    settingsButton = new QPushButton("设置");

    // 创建录制指示器
    recordingIndicator = new QLabel(videoButton);
    recordingIndicator->setFixedSize(10, 10);
    recordingIndicator->setStyleSheet("background-color: red; border-radius: 5px;");
    recordingIndicator->hide();
    recordingIndicator->move(videoButton->width() - 15, 5);  // 位置在按钮右上角

    // 设置按钮样式
    buttonStyle = "QPushButton {"
                          "    background-color: #2b2b2b;"
                          "    color: white;"
                          "    border-radius: 5px;"
                          "    padding: 8px;"
                          "    margin: 2px;"
                          "}"
                          "QPushButton:hover {"
                          "    background-color: #3b3b3b;"
                          "}";

    // 连接拍照按钮的信号
    connect(cameraButton, &QPushButton::clicked, this, &EndoscopeWindow::captureImage);

    // 连接录像按钮信号
    connect(videoButton, &QPushButton::clicked, this, &EndoscopeWindow::toggleRecording);

    autoButton->setStyleSheet(buttonStyle);
    cameraButton->setStyleSheet(buttonStyle);
    videoButton->setStyleSheet(buttonStyle);
    freezeButton->setStyleSheet(buttonStyle);
    saveButton->setStyleSheet(buttonStyle);
    settingsButton->setStyleSheet(buttonStyle);


    // 创建美颜按钮和菜单
    beautyButton = new QPushButton("美颜");
    beautyButton->setStyleSheet(buttonStyle);
    
    beautyMenu = new QMenu(this);
    smoothAction = beautyMenu->addAction("磨皮");
    whiteningAction = beautyMenu->addAction("美白");
    
    smoothAction->setCheckable(true);
    whiteningAction->setCheckable(true);
    
    beautyButton->setMenu(beautyMenu);
    
    connect(smoothAction, &QAction::triggered, this, &EndoscopeWindow::toggleSmoothing);
    connect(whiteningAction, &QAction::triggered, this, &EndoscopeWindow::toggleWhitening);
    
    // 添加美颜按钮到右侧面板
    rightLayout->addWidget(beautyButton);
}
void EndoscopeWindow::handleCameraError(QCamera::Error error)
{
    switch (error) {
    case QCamera::NoError:
        break;
    case QCamera::CameraError:
        cout << "Camera error occurred: General Camera error" << endl;
        break;
    default:
        cout << "Camera error occurred: Unknown error" << endl;
    }
}

// 实现拍照功能
void EndoscopeWindow::captureImage()
{
    cout << "Capture image button clicked" << endl;
    cout << "Camera is active: " << (camera ? camera->isActive() : false) << endl;
    if (camera && camera->isActive()) {
        // 创建保存目录
        QString saveDir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/YIGasMed";
        QDir().mkpath(saveDir);
        
        // 生成文件名（使用时间戳）
        QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
        QString fileName = saveDir + "/IMG_" + timestamp + ".jpg";

        cout << "Saving image to: " << fileName.toStdString() << endl;
        
        // 捕获图像
        imageCapture->captureToFile(fileName);
    } else {
        cout << "Camera is not active" << endl;
    }
}

// 处理图片保存完成的槽函数
void EndoscopeWindow::imageSaved(int id, const QString &fileName)
{
    cout << "Image saved as: " << fileName.toStdString() << endl;
}

// 添加更新时间的槽函数
void EndoscopeWindow::updateDateTime()
{
    QString currentTime = QDateTime::currentDateTime().toString("hh:mm:ss");
    timeLabel->setText(currentTime);
}

// 实现录像控制方法
void EndoscopeWindow::toggleRecording()
{
    if (!isRecording) {
        // 开始录像
        QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
        QString fileName = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation) 
                         + "/YIGasMed/VID_" + timestamp + ".mp4";
        
        mediaRecorder->setOutputLocation(QUrl::fromLocalFile(fileName));
        mediaRecorder->record();
        isRecording = true;

        recordingTimer->setInterval(50);  // 设置更快的更新间隔使动画更流畅
        recordingTimer->start();
        videoButton->setText("停止");
        recordingIndicator->show();

    } else {
        // 停止录像
        mediaRecorder->stop();
        isRecording = false;
        recordingTimer->stop();
        videoButton->setText("录像");
        videoButton->setStyleSheet(buttonStyle);  // 恢复原始样式
        recordingIndicator->hide();
    }
}

// 实现录像指示器更新
void EndoscopeWindow::updateRecordingIndicator()
{
    if (isRecording) {
        recordingIndicator->show();
        
        // 更新脉冲动画
        if (pulseGrowing) {
            pulseScale += 0.1;
            if (pulseScale >= 1.5) {
                pulseGrowing = false;
            }
        } else {
            pulseScale -= 0.1;
            if (pulseScale <= 1.0) {
                pulseGrowing = true;
            }
        }

        // 应用缩放动画
        int size = 10 * pulseScale;
        recordingIndicator->setFixedSize(size, size);
        recordingIndicator->setStyleSheet(QString("background-color: red; border-radius: %1px;").arg(size/2));
        recordingIndicator->move(videoButton->width() - size - 5, 5);
        
        videoButton->setText("停止");
    } else {
        recordingIndicator->hide();
    }
}

// 处理录像错误
void EndoscopeWindow::handleRecordingError(QMediaRecorder::Error error)
{
    cout << "Recording error occurred: " << error << endl;
    isRecording = false;
    recordingTimer->stop();
    videoButton->setText("录像");
}

// 处理录像完成
void EndoscopeWindow::handleRecordingFinished()
{
    if (mediaRecorder->recorderState() == QMediaRecorder::StoppedState) {
        cout << "Recording finished and saved" << endl;
    }
}

void EndoscopeWindow::toggleSmoothing()
{
    isSmoothing = smoothAction->isChecked();
    cout << "Smoothing effect toggled: " << (isSmoothing ? "on" : "off") << endl;
}

void EndoscopeWindow::toggleWhitening()
{
    isWhitening = whiteningAction->isChecked();
    cout << "Whitening effect toggled: " << (isWhitening ? "on" : "off") << endl;
}
void EndoscopeWindow::processFrame(QVideoFrame &frame)
{
    if (!isSmoothing && !isWhitening) return;

    // 先映射原始帧为只读
    if (!frame.map(QVideoFrame::ReadOnly)) {
        cout << "Failed to map original frame" << endl;
        return;
    }

    // 获取原始图像
    QImage originalImage = frame.toImage();
    frame.unmap();

    if (originalImage.isNull()) {
        cout << "Failed to convert frame to image" << endl;
        return;
    }

    // 转换为合适的格式
    QImage image = originalImage.convertToFormat(QImage::Format_ARGB32);
    
    // 转换 QImage 到 OpenCV Mat
    cv::Mat mat(image.height(), image.width(), CV_8UC4, image.bits(), image.bytesPerLine());
    cv::Mat matBGR;
    cv::cvtColor(mat, matBGR, cv::COLOR_BGRA2BGR);
    
    if (isSmoothing) {
        // 磨皮效果增强
        cv::Mat blurred;
        cv::GaussianBlur(matBGR, blurred, cv::Size(7, 7), 0, 0);
        
        cv::Mat temp;
        cv::bilateralFilter(matBGR, temp, 9, 75, 75);
        
        // 细节保留
        cv::Mat detail = matBGR - blurred;
        cv::Mat result = temp + detail * 0.5;
        
        // 融合
        cv::addWeighted(matBGR, 0.2, result, 0.8, 0, matBGR);
    }
    
    if (isWhitening) {
        // 美白效果增强
        cv::Mat lab;
        cv::cvtColor(matBGR, lab, cv::COLOR_BGR2Lab);
        
        std::vector<cv::Mat> lab_planes;
        cv::split(lab, lab_planes);
        
        // 增强亮度和对比度
        cv::Mat L = lab_planes[0];
        double alpha = 1.3;  // 对比度增强
        double beta = 15.0;   // 亮度增强
        
        L.convertTo(L, -1, alpha, beta);
        
        // 限制过亮区域
        cv::threshold(L, L, 250, 250, cv::THRESH_TRUNC);
        
        // 调整肤色
        cv::Mat a = lab_planes[1];
        cv::Mat b = lab_planes[2];
        a = a * 0.95;  // 减少红色分量
        b = b * 0.95;  // 调整黄色分量
        
        lab_planes[0] = L;
        lab_planes[1] = a;
        lab_planes[2] = b;
        
        cv::merge(lab_planes, lab);
        cv::cvtColor(lab, matBGR, cv::COLOR_Lab2BGR);
    }
    
    // 转换回 RGBA
    cv::Mat matRGBA;
    cv::cvtColor(matBGR, matRGBA, cv::COLOR_BGR2BGRA);
    
    // 创建新的 QImage
    QImage processedImage(matRGBA.data, matRGBA.cols, matRGBA.rows, matRGBA.step, QImage::Format_ARGB32);
    processedImage = processedImage.copy(); // 创建深拷贝

    // 创建新的视频帧
    frame = QVideoFrame(processedImage);
}